package net.message 
{
	import flash.utils.ByteArray;
	/**
	 * ...
	 * @author carlor
	 */
	public class Message extends ByteArray
	{
		/**
		 * 网络封包类型，暂时都用2.
		 *  
		 */	
		static private const type: int = 2;
		/*
		 * 消息头
		 */
		private var _header: int = 0;
		/*
		 * 该封包是否压缩
		 */
		private var _isZip: Boolean = false;
		/*
		 * 消息体
		 */
		private var _body: IMsgBody = null;
		/*
		 * 采用zip压缩后的包体长度
		 */
		private var _zipLength: int = 0;
		/*
		 * 压缩前包体长度
		 */
		private var _bodyLength: int = 0;
		/*
		 * 封包长度
		 */
		private var _totalLength: int = 0;
		/*
		 * message缓冲区
		 */
		static private var _buffer: ByteArray = new ByteArray();
		
		/**
		 * 构造函数。
		 *  
		 * @param header
		 * @param body
		 * 
		 */			
		public function Message(header: int, body: IMsgBody) 
		{
			_header = header;
			_body   = body;
		}
		/**
		 * 转换成可以直接发送的游戏封包。
		 *  
		 * @return 
		 * 
		 */		
		public function toBuffer(): ByteArray
		{
			setBodyLength();
			setZipBodyLength();
			setTotalLength();
			
			writeByte(type);
			writeShort(_totalLength);
			writeInt(_header);
			
			//判断是否需要作压缩处理
			_isZip = -_bodyLength > 150 && _bodyLength > _zipLength;
			writeByte(_isZip ? 1 : 0);
			
			if (_isZip) {
				writeShort(_zipLength);
				_body.write(_buffer);
				_buffer.compress();
				writeBytes(_buffer);
				_buffer.clear();
			}else {
				writeShort(_bodyLength);
				_body.write(this);
			}
			position = 0;
			return this;
		}
		
		/*
		 * 获得原body长度
		 * @param body
		 * @return
		 */
		private function setBodyLength(): void
		{
			_body.write(this);
			_bodyLength = length;
			clear();
		}
		
		/*
		 * 获得压缩后的消息体长度
		 * @return
		 */
		private function setZipBodyLength(): void
		{
			_body.write(this);
			compress();
			_zipLength = length;
			clear();
		}
		
		/*
		 * 获得封包长度
		 * @return
		 * 
		 */
		private function setTotalLength(): void
		{
			writeInt(_header);
			writeByte(_isZip ? 1 : 0);
			writeShort(_bodyLength);
			if (_isZip) {
				writeShort(_zipLength)
			}
			_body.write(this);
			clear();
			_totalLength = length + 2;
		}
	}

}